package com.jic.member.impl;

import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.common.utils.DateUtils;
import com.jic.manager.api.rest.UserSysDeptApi;
import com.jic.member.constant.consist.ResponseCode;
import com.jic.member.constant.enums.LabelEnums;
import com.jic.member.exception.AppRuntimeException;
import com.jic.member.mapper.TGroupLabelRelationMapper;
import com.jic.member.mapper.TLabelMapper;
import com.jic.member.mapper.TLabelMemberRelationMapper;
import com.jic.member.mapper.TUserGroupMapper;
import com.jic.member.entity.TGroupLabelRelation;
import com.jic.member.entity.TLabel;
import com.jic.member.entity.TUserGroup;
import com.jic.member.request.*;
import com.jic.member.response.TUserGroupResponse;
import com.jic.member.service.TLabelService;
import com.jic.member.service.TUserGroupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 接口实现类
 *
 * @author : 建投数据科技(山东)有限公司
 * @version : v1.0.0
 * @email :
 * @since : 2020-03-09 10:12:20
 */
@Service
@Slf4j
public class TUserGroupServiceImpl implements TUserGroupService {

    @Resource
    private TUserGroupMapper mapper;
    @Resource
    private TGroupLabelRelationMapper tGroupLabelRelationMapper;
    @Resource
    private TLabelMemberRelationMapper labelMemberRelationMapper;
    @Resource
    private TLabelMapper labelMapper;
    @Resource
    private UserSysDeptApi sysDeptApi;
    @Resource
    private TLabelService tLabelService;


    /**
     * 新增记录
     *
     * @param request 需要保存的入参实体类
     * @return int 是否保存成功
     */
    @Override
    public Long save(TUserGroup request) {
        int flag = mapper.insertSelective(request);
        if (flag == 1) {
            return request.getId();
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "新增失败");
        }
    }


    /**
     * 保存或修改记录信息
     *
     * @param request 需要保存的入参实体类
     * @return int 是否保存或修改成功
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:09
     */
    @Override
    public int saveOrUpdate(TUserGroup request) {
        log.info("保存或修改记录信息，入参 = {}", JSONObject.toJSONString(request));
        try {
            if (request == null) {
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "入参为空");
            }
            if (request.getId() != null) {
                log.info("保存或修改记录信息，修改，入参 = {}", JSONObject.toJSONString(request));
                int flag = mapper.updateByPrimaryKey(request);
                if (flag == 1) {
                    return 1;
                }
            } else {
                log.info("保存或修改记录信息，保存，入参 = {}", JSONObject.toJSONString(request));
                int flag = mapper.insertSelective(request);
                if (flag == 1) {
                    return 1;
                } else {
                    throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改失败");
                }
            }
        } catch (Exception e) {
            log.error("用户保存或修改失败", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "用户保存或修改失败");
        }
        return -1;
    }

    /**
     * 删除记录
     *
     * @param request 需要删除,含有主键的入参实体类
     * @return int 是否删除成功
     */
    @Override
    public int deleteByPrimaryKey(TUserGroup request) {
        int flag = mapper.deleteByPrimaryKey(request);
        if (flag == 1) {
            return 1;
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "删除失败");
        }
    }


    /**
     * 逻辑删除记录
     *
     * @param request 含有主键的逻辑删除实体类
     * @return int 是否逻辑删除成功
     */
    @Override
    public int deleteByPrimaryKeyLogically(TUserGroup request) {
        request.setDeleteFlag(1);
        int flag = mapper.updateByPrimaryKey(request);
        if (flag == 1) {
            return 1;
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "逻辑删除记录失败");
        }
    }


    /**
     * 修改
     *
     * @param request
     * @return
     */
    @Override
    public int updateByPrimaryKeySelective(TUserGroup request) {
        try {
            log.info("修改记录");
            TUserGroup param = new TUserGroup();
            BeanUtils.copyProperties(request, param);
            int flag = mapper.updateByPrimaryKeySelective(param);
            if (flag == 1) {
                return 1;
            } else {
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改记录失败");
            }
        } catch (Exception e) {
            log.error("修改记录失败", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改记录失败");
        }

    }

    /**
     * 记录详情
     *
     * @param request 查询的入参实体类
     * @return 数据库查询到的实体类
     */
    @Override
    public TUserGroup getByPrimaryKey(TUserGroup request) {
        return mapper.selectByPrimaryKey(request);
    }


    /**
     * 不分页查询
     *
     * @param request 不分页查询入参实体类
     * @return 数据库查到的实体类列表
     */
    @Override
    public List<TUserGroup> listAllRecord(TUserGroup request) {
        //分页处理
        request.setDeleteFlag(0);
        return mapper.selectBySelective(request);
    }

    /**
     * 用户组添加
     *
     * @param tUserGroupAddOrUpdateRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResult<String> updateUserGroup(TUserGroupAddOrUpdateRequest tUserGroupAddOrUpdateRequest) {
        try {
            // 更新用户组
            TUserGroup tUserGroup = new TUserGroup();
            tUserGroup.setId(tUserGroupAddOrUpdateRequest.getId());
            tUserGroup.setUserGroupNumber(tUserGroupAddOrUpdateRequest.getUserGroupNumber());
            tUserGroup.setGroupType(tUserGroupAddOrUpdateRequest.getGroupType());
            tUserGroup.setGroupDescription(tUserGroupAddOrUpdateRequest.getGroupDescription());
            tUserGroup.setDeptId(tUserGroupAddOrUpdateRequest.getAdminOperate().getDeptId());
            tUserGroup.setCreateTime(new Date());
            tUserGroup.setUserGroupName(tUserGroupAddOrUpdateRequest.getUserGroupName());
            tUserGroup.setId(tUserGroupAddOrUpdateRequest.getId());
            tUserGroup.setUpdateTime(new Date());
            tUserGroup.setDeleteFlag(0);
            mapper.updateByPrimaryKey(tUserGroup);
        } catch (Exception e) {
            log.error("保存或修改用户组失败:{}", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "保存或修改用户组失败");
        }
        return RestResult.success("操作成功");
    }

    @Override
    public RestResult<PageResult<TUserGroupResponse>> queryPage(TUserGroupRequest request) {
        PageResult<TUserGroupResponse> result = new PageResult<>();
        // 没有平台id则为当前用户平台id
        if (null == request.getDeptId()) {
            request.setDeptId(request.getAdminOperate().getDeptId());
        }
        Long pageCount = mapper.queryPageCount(request);
        if (0 == pageCount) {
            result.setTotal(pageCount);
            result.setRows(null);
            return RestResult.success(result);
        }
        request.setStart((request.getStart() - 1) * request.getLimit());
        List<TUserGroupResponse> responses = mapper.queryPage(request).stream().map(item -> {
            TUserGroupResponse response = new TUserGroupResponse();
            BeanUtils.copyProperties(item, response);
//            if (null != item.getDeptId()) {
//                RestResult<String> stringRestResult = sysDeptApi.queryDeptNameById(item.getDeptId());
//                response.setDeptName(stringRestResult.getData());
//            } else {
//                response.setDeptName("-");
//            }
            return response;
        }).collect(Collectors.toList());

        result.setTotal(pageCount);
        result.setRows(responses);
        return RestResult.success(result);
    }

    /**
     * 筛选会员
     *
     * @param tUserGroupAddOrUpdateRequest
     * @return
     */
    @Override
    public List<String> screeningMember(TUserGroupAddOrUpdateRequest tUserGroupAddOrUpdateRequest) {
        TGroupLabelRelation tGroupLabelRelation = new TGroupLabelRelation();
        tGroupLabelRelation.setUserGroupId(tUserGroupAddOrUpdateRequest.getId());
        List<Long> deptIdLongs = tGroupLabelRelationMapper.selectDeptIdByUserGroupId(tGroupLabelRelation);
        List<List<String>> list = new ArrayList<>();
        for (int i = 0; i < deptIdLongs.size(); i++) {
            tGroupLabelRelation.setDeptId(deptIdLongs.get(i));
            List<TGroupLabelRelation> tGroupLabelRelationList = tGroupLabelRelationMapper.selectBySelective(tGroupLabelRelation);
            //转成对象
            List<TripLabelRequest> tripLabelRequestList = tGroupLabelRelationList.stream().map(temp -> {
                TripLabelRequest bo = new TripLabelRequest();
                bo.setLabelId(temp.getLabelId());
                return bo;
            }).filter(item -> item != null).collect(Collectors.toList());
            //for 平台集合
            if (tripLabelRequestList != null) {
                List<List<String>> list1 = this.memberForLabel(tripLabelRequestList);
                //组织内取交集
                List<String> stringList = this.aCollectionOfIntersection(list1);
                list.add(stringList);
            }
        }
        List<String> memberList = this.andSet(list);

        return memberList;
    }

    /**
     * 通过用户组和标签Ids查询会员
     *
     * @param tripLabelArrayRequest
     * @return
     */
    @Override
    public List<String> queryMemberIds(TripLabelArrayRequest tripLabelArrayRequest) {
        List<String> stringList = new ArrayList<>();
        //标签查询会员多选时为“交集”的关系
        if (CollectionUtils.isNotEmpty(tripLabelArrayRequest.getTripLabelRequestList())) {
            List<List<String>> list = this.memberForLabel(tripLabelArrayRequest.getTripLabelRequestList());
            //组织内取交集
            stringList = this.aCollectionOfIntersection(list);
        }
        if (CollectionUtils.isNotEmpty(tripLabelArrayRequest.getTripUserGroupRequestList())) {
            List<List<String>> list = new ArrayList<List<String>>();
            for (int i = 0; i < tripLabelArrayRequest.getTripUserGroupRequestList().size(); i++) {
                list.add(this.memberForUserGroups(tripLabelArrayRequest.getTripUserGroupRequestList().get(i)));
            }
            //用户组之间的关系，1交集、2并集
            if (tripLabelArrayRequest.getRelation() != null && tripLabelArrayRequest.getRelation() == 1) {
                stringList = this.aCollectionOfIntersection(list);
            } else if (tripLabelArrayRequest.getRelation() != null && tripLabelArrayRequest.getRelation() == 2) {
                stringList = this.andSet(list);
            }
        }

        return stringList;
    }

    /**
     * 刷新分组
     *
     * @param tUserGroupAddOrUpdateRequest
     * @return
     */
    @Override
    public RestResult<String> refreshGroup(TUserGroupAddOrUpdateRequest tUserGroupAddOrUpdateRequest) {
        try {
            //年龄
            tLabelService.getMemberInfoByAge();
            //会员类型
            tLabelService.getMemberInfoByMemberType();
            //会员等级
            tLabelService.getMemberInfoByMemberGrade();
            //性别
            tLabelService.getMemberInfoBySex();

            int membership = this.screeningMember(tUserGroupAddOrUpdateRequest).size();
            TUserGroup tUserGroup = new TUserGroup();
            tUserGroup.setId(tUserGroupAddOrUpdateRequest.getId());
            tUserGroup.setUpdateTime(new Date());
            tUserGroup.setUserGroupNumber(membership);
            mapper.updateByPrimaryKey(tUserGroup);
        } catch (Exception e) {
            log.error("刷新分组失败:{}", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "刷新分组失败");
        }
        return RestResult.success("成功");
    }

    /**
     * 定时刷新分组
     *
     * @return
     */
    @Override
    public RestResult<String> timeToRefreshGrouping() {
        log.info("定时刷新分组============>start", DateUtils.convert(new Date()));
        TUserGroup tUserGroup = new TUserGroup();
        tUserGroup.setGroupType(1);
        List<TUserGroup> tUserGroupList = mapper.selectBySelective(tUserGroup);
        tUserGroupList.forEach(tUserGroup1 -> {
            TUserGroupAddOrUpdateRequest tUserGroupAddOrUpdateRequest = new TUserGroupAddOrUpdateRequest();
            tUserGroupAddOrUpdateRequest.setId(tUserGroup1.getId());
            int membership = this.screeningMember(tUserGroupAddOrUpdateRequest).size();
            tUserGroup1.setId(tUserGroupAddOrUpdateRequest.getId());
            tUserGroup1.setUpdateTime(new Date());
            tUserGroup1.setUserGroupNumber(membership);
            mapper.updateByPrimaryKey(tUserGroup1);
        });
        log.info("定时刷新分组============>end", DateUtils.convert(new Date()));
        return RestResult.success("成功");
    }

    /**
     * 通过用户组查询会员
     *
     * @param tripUserGroupRequest
     * @return
     */
    @Override
    public List<String> queryMemberIdsByUserGroup(TripUserGroupRequest tripUserGroupRequest) {
        return this.memberForUserGroups(tripUserGroupRequest);
    }

    /**
     * 用户组更新标签表
     *
     * @param tUserGroupAddOrUpdateRequest
     * @return
     */
    @Override
    public RestResult<String> updateLabelTableUserGroups(TUserGroupAddOrUpdateRequest tUserGroupAddOrUpdateRequest) {
        try {
            TGroupLabelRelation groupLabelRelation = new TGroupLabelRelation();
            groupLabelRelation.setUserGroupId(tUserGroupAddOrUpdateRequest.getId());
            groupLabelRelation.setDeptId(tUserGroupAddOrUpdateRequest.getDeptId() == null ?
                    tUserGroupAddOrUpdateRequest.getAdminOperate().getDeptId() : tUserGroupAddOrUpdateRequest.getDeptId());
            tGroupLabelRelationMapper.deleteByUserGroup(groupLabelRelation);
            //for 平台集合
            if (tUserGroupAddOrUpdateRequest.getLabelIds() != null && tUserGroupAddOrUpdateRequest.getLabelIds().size() > 0) {
                for (int i = 0; i < tUserGroupAddOrUpdateRequest.getLabelIds().size(); i++) {
                    // 插入标签关联表
                    TGroupLabelRelation tGroupLabelRelation = new TGroupLabelRelation();
                    tGroupLabelRelation.setLabelId(tUserGroupAddOrUpdateRequest.getLabelIds().get(i));
                    tGroupLabelRelation.setUserGroupId(tUserGroupAddOrUpdateRequest.getId());
                    tGroupLabelRelation.setCreateTime(new Date());
                    tGroupLabelRelation.setDeptId(tUserGroupAddOrUpdateRequest.getDeptId() == null ?
                            tUserGroupAddOrUpdateRequest.getAdminOperate().getDeptId() : tUserGroupAddOrUpdateRequest.getDeptId());
                    tGroupLabelRelationMapper.insertSelective(tGroupLabelRelation);
                }
            }
        } catch (Exception e) {
            log.error("用户组更新标签表:{}", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "用户组更新标签表");
        }
        return RestResult.success("操作成功");
    }

    /**
     * 用组ID查询会员
     *
     * @param tripUserGroupRequest
     * @return
     */
    private List<String> memberForUserGroups(TripUserGroupRequest tripUserGroupRequest) {
        TGroupLabelRelation tGroupLabelRelation = new TGroupLabelRelation();
        tGroupLabelRelation.setUserGroupId(tripUserGroupRequest.getUserGroupId());
        List<Long> labelLongs = tGroupLabelRelationMapper.selectByUserGroupId(tGroupLabelRelation);
        if (labelLongs.size() > 0) {
            TLabelMemberRelationRequest tLabelMemberRelationRequest = new TLabelMemberRelationRequest();
            tLabelMemberRelationRequest.setLabelIds(labelLongs);
            return labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest);
        }
        return new ArrayList<>();
    }

    /**
     * 查询通过标签ids查询所有会员
     *
     * @param tripLabelRequestList
     * @return
     */
    private List<List<String>> memberForLabel(List<TripLabelRequest> tripLabelRequestList) {
        //组织内取交集集合
        List<List<String>> list = new ArrayList<List<String>>();
        //for 平台集合
        if (CollectionUtils.isNotEmpty(tripLabelRequestList)) {
            List<Long> sexLongs = new ArrayList<>();
            List<Long> gradeLongs = new ArrayList<>();
            List<Long> memberTypeLongs = new ArrayList<>();
            List<Long> ageLongs = new ArrayList<>();
            List<Long> custom = new ArrayList<>();
            for (int i = 0; i < tripLabelRequestList.size(); i++) {
                //查询标签数据
                TLabel tLabel = new TLabel();
                tLabel.setId(tripLabelRequestList.get(i).getLabelId());
                tLabel = labelMapper.selectByPrimaryKey(tLabel);
                if (tLabel != null) {
                    //1.模型标签 2.自定义标签
                    if (tLabel.getLabelType() == 1) {
                        TLabel tLabel1 = new TLabel();
                        tLabel1.setId(tLabel.getPid());
                        tLabel1 = labelMapper.selectByPrimaryKey(tLabel1);
                        //性别
                        if (tLabel1 != null) {
                            if (StringUtils.equals(tLabel1.getLabelName(), LabelEnums.SEX.getValue())) {
                                sexLongs.add(tLabel.getId());
                            } else if (StringUtils.equals(tLabel1.getLabelName(), LabelEnums.MEMBERSHIP_GRADE.getValue())) {
                                gradeLongs.add(tLabel.getId());
                            } else if (StringUtils.equals(tLabel1.getLabelName(), LabelEnums.MEMBER_TYPE.getValue())) {
                                memberTypeLongs.add(tLabel.getId());
                            } else if (StringUtils.equals(tLabel1.getLabelName(), LabelEnums.AGE.getValue())) {
                                ageLongs.add(tLabel.getId());
                            }
                        }
                    } else {
                        custom.add(tLabel.getId());
                    }

                }
            }
            TLabelMemberRelationRequest tLabelMemberRelationRequest = new TLabelMemberRelationRequest();
            //性别
            if (sexLongs.size() > 0) {
                tLabelMemberRelationRequest.setLabelIds(sexLongs);
                list.add(labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest));
            }
            //会员等级
            if (gradeLongs.size() > 0) {
                tLabelMemberRelationRequest.setLabelIds(gradeLongs);
                list.add(labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest));
            }
            //会员类型
            if (memberTypeLongs.size() > 0) {
                tLabelMemberRelationRequest.setLabelIds(memberTypeLongs);
                list.add(labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest));
            }
            //年龄
            if (ageLongs.size() > 0) {
                tLabelMemberRelationRequest.setLabelIds(ageLongs);
                list.add(labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest));
            }
            //自定义标签
            if (custom.size() > 0) {
                tLabelMemberRelationRequest.setLabelIds(custom);
                list.add(labelMemberRelationMapper.queryBatchByLabelIds(tLabelMemberRelationRequest));
            }

        }
        return list;
    }

    /**
     * 多个集合的并集
     *
     * @param list
     * @return
     */
    private List<String> andSet(List<List<String>> list) {
        List<String> set = new ArrayList<>();
        if (list == null) {
            list = new ArrayList<List<String>>();
        }
        int size = list.size();
        if (size > 1) {
            for (int i = 0; i < size; i++) {
                int j = i + 1;
                if (j < size) {
                    list.get(0).removeAll(list.get(j));
                    list.get(0).addAll(list.get(j));
                    if (i == size - 2) {
                        List<String> resultList = list.get(0);
                        for (String name : resultList) {
                            set.add(name);
                        }
                    }
                }
            }
        } else {
            //只有一个集合则直接插入结果
            for (List<String> list2 : list) {
                for (String name : list2) {
                    set.add(name);
                }
            }
        }
        return set;
    }

    /**
     * 取多个集合的交集
     *
     * @param list
     * @return
     */
    private List<String> aCollectionOfIntersection(List<List<String>> list) {
        List<String> set = new ArrayList<>();
        int size = list.size();
        if (size > 1) {
            //取集合中的交集
            for (int i = 0; i < size; i++) {
                int j = i + 1;
                if (j < size) {
                    list.get(0).retainAll(list.get(j));
                    if (i == size - 2) {
                        List<String> resultList = list.get(0);
                        for (String name : resultList) {
                            set.add(name);
                        }
                    }
                }
            }
        } else {
            //只有一个集合则不取交集
            for (List<String> list2 : list) {
                for (String name : list2) {
                    set.add(name);
                }
            }
        }
        return set;
    }

    @Override
    public RestResult<String> deleteById(TUserGroup tUserGroup) {
        try {
            log.info("删除用户分组");
            int flag = mapper.deleteById(tUserGroup);
            if (flag == 1) {
                return RestResult.success("删除成功!");
            }
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "删除用户分组失败");
        } catch (Exception e) {
            log.error("删除用户分组失败", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "删除用户分组失败");
        }
    }
}
